<html lang="en">

    <head>
        <title>
            CshtmlComponent - ASP.NET Core MVC and Razor Pages Component V4.1.0
        </title>

        <meta name="description" content="CshtmlComponent, a component for ASP.NET Core MVC and Razor Pages. No Blazor.">
        <meta name="keywords" content="ASP, NET, .NET, Core, C#, razor, cshtml, component, code, mvc, razor pages">
        <meta name="robots" content="index, follow">
        <meta name="language" content="English">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

        <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">

        <link rel="apple-touch-icon" sizes="180x180" href="visualization/favicon/apple-touch-icon.png">
        <link rel="icon" type="image/png" sizes="32x32" href="visualization/favicon/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="visualization/favicon/favicon-16x16.png">
        <link rel="manifest" href="visualization/favicon/site.webmanifest">
        <link rel="mask-icon" href="visualization/favicon/safari-pinned-tab.svg" color="#0355ea">
        <link rel="shortcut icon" href="visualization/favicon/favicon.ico">
        <meta name="msapplication-TileColor" content="#020202">
        <meta name="msapplication-config" content="visualization/favicon/browserconfig.xml">
        <meta name="theme-color" content="#020202">

        <!-- Libraries -->
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" crossorigin="anonymous">
        <link rel="stylesheet" href="https://hyper-nav.acmion.com/+/dist/css/hyper-nav-default.min.css">
        <link rel="stylesheet" href="https://negatronic-acmion.acmion.com/+/css/negatronic.css">

        <!-- Custom -->
        <link rel="stylesheet" href="/Web/css/main.css">

        <!-- Icons -->
        <link rel="apple-touch-icon" sizes="180x180" href="/+/favicon/apple-touch-icon.png">
        <link rel="icon" type="image/png" sizes="32x32" href="/+/favicon/favicon-32x32.png">
        <link rel="icon" type="image/png" sizes="16x16" href="/+/favicon/favicon-16x16.png">
        <link rel="manifest" href="/+/favicon/site.webmanifest">
        <link rel="mask-icon" href="/+/favicon/safari-pinned-tab.svg" color="#ff0000">
        <link rel="shortcut icon" href="/+/favicon/favicon.ico">
        <meta name="msapplication-TileColor" content="#ffffff">
        <meta name="msapplication-config" content="/+/favicon/browserconfig.xml">
        <meta name="theme-color" content="#ffffff">
    </head>

    <body>
        <header>
            <nav class="hn-menu hn-top hn-fixed hn-shadow">
                <input type="checkbox" name="hn-top-state" class="hn-input-state hn-input-state-nav hn-hide-desktop" id="hn-nav-cb">

                <div class="hn-nav container-md p-0">
                    <div class="hn-section hn-section-brand">
                        <div class="hn-item">
                            <a id="hn-logo" class="hn-link" href="/">
                                <span class="hn-icon hn-size-auto">
                                    <img src="/+/assets/icon.svg" class="acmion-icon">
                                </span>
                                <span class="hn-content">
                                    <span class="acmion-logo">
                                        CshtmlComponent
                                    </span>
                                </span>
                            </a>
                        </div>

                        <div class="hn-spacer"></div>

                        <label class="hn-item hn-input hn-input-nav hn-hide-desktop" for="hn-nav-cb">
                            <span class="hn-link">
                                <span class="hn-content">
                                    <span class="hn-input-active ">
                                        <i class="ri-close-line"></i>
                                    </span>
                                    <span class="hn-input-default">
                                        <i class="ri-menu-line"></i>
                                    </span>
                                </span>
                            </span>
                        </label>

                    </div>
                    <div class="hn-section hn-section-body">
                        <div class="hn-spacer"></div>

                        <div class="hn-item">
                            <a class="hn-link" href="#home">
                                <span class="hn-content">
                                    Home
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="#examples">
                                <span class="hn-content">
                                    Examples
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="#core">
                                <span class="hn-content">
                                    Core
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="#usage">
                                <span class="hn-content">
                                    Usage
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="#change-log">
                                <span class="hn-content">
                                    Changelog
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="#credits">
                                <span class="hn-content">
                                    Credits
                                </span>
                            </a>
                        </div>
                        <div class="hn-item">
                            <a class="hn-link" href="https://github.com/Acmion/CshtmlComponent">
                                <span class="hn-content">
                                    GitHub
                                </span>
                            </a>
                        </div>
                    </div>
                </div>

                <label class="hn-overlay" for="hn-nav-cb">
                </label>
            </nav>
        </header>

        <div class="scroll-anchor-height"></div>

        <main class="container">
            <section>
                <h1 class="scroll-anchor" id="home">
                    CshtmlComponent - ASP.NET Core MVC and Razor Pages Component V4.1.0
                </h1>

                <p>
                    Using components in ASP.NET Core MVC or Razor Pages, out of the box, is annoying to say the least (read: a real PITA).
                    Tag Helpers do not support Razor syntax, View Components can not access nested child content. Razor Components do not support
                    runtime compilation and do not work too well in standard MVC or Razor Page projects. <strong>CshtmlComponent</strong>,
                    from the perspective of an MVC or Razor Pages app, combines the best features of these technologies.
                </p>
                <p>
                    <strong>Note:</strong> This document assumes that you have a good understanding of C#, Razor markup and ASP.NET Core.
                    <br>
                    <strong>Install the <a href="https://www.nuget.org/packages/Acmion.CshtmlComponent/">Nuget package</a>.</strong>
                    <br>
                    <strong>See more detailed <a href="#usage">Usage instructions</a></strong>.
                </p>

                <div class="p-2"></div>

                <div class="row">
                    <div class="col-md-3">
                        <div class="card bg-light h-100" style="border-color: #24E260;">
                            <div class="card-body card-body-success">
                                <h4 class="card-title">
                                    CshtmlComponent
                                </h4>
                                <ul class="feature-list">
                                    <li>
                                        Razor Syntax
                                    </li>
                                    <li>
                                        Nested Child Content
                                    </li>
                                    <li>
                                        Runtime Compilation
                                    </li>
                                    <li>
                                        MVC &amp; Razor Pages
                                    </li>
                                    <li>
                                        Lenient File Structure
                                    </li>
                                    <li>
                                        Named Slots
                                    </li>
                                    <li>
                                        Reference Capturing
                                    </li>
                                    <li>
                                        One-Off Content <sup>[1]</sup>
                                    </li>
                                    <li>
                                        Head Content Injection <sup>[2]</sup>
                                    </li>
                                    <li>
                                        Body Content Injection <sup>[3]</sup>
                                    </li>
                                    <li>
                                        Render to IHtmlContent
                                    </li>
                                    <li>
                                        Render to String
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-light border-danger h-100">
                            <div class="card-body">
                                <h4 class="card-title">
                                    Tag Helper
                                </h4>
                                <ul class="feature-list">
                                    <li class="feature-not-enabled">
                                        Razor Syntax
                                    </li>
                                    <li>
                                        Nested Child Content
                                    </li>
                                    <li class="feature-not-enabled">
                                        Runtime Compilation
                                    </li>
                                    <li>
                                        MVC &amp; Razor Pages
                                    </li>
                                    <li>
                                        Lenient File Structure
                                    </li>
                                    <li class="feature-not-enabled">
                                        Named Slots
                                    </li>
                                    <li class="feature-not-enabled">
                                        Reference Capturing
                                    </li>
                                    <li class="feature-not-enabled">
                                        One-Off Content <sup>[1]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Head Content Injection <sup>[2]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Body Content Injection <sup>[3]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Render to IHtmlContent
                                    </li>
                                    <li class="feature-not-enabled">
                                        Render to String
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-light border-danger h-100">
                            <div class="card-body">
                                <h4 class="card-title">
                                    View Component
                                </h4>
                                <ul class="feature-list">
                                    <li>
                                        Razor Syntax
                                    </li>
                                    <li class="feature-not-enabled">
                                        Nested Child Content
                                    </li>
                                    <li>
                                        Runtime Compilation
                                    </li>
                                    <li>
                                        MVC &amp; Razor Pages
                                    </li>
                                    <li class="feature-not-enabled">
                                        Lenient File Structure
                                    </li>
                                    <li class="feature-not-enabled">
                                        Named Slots
                                    </li>
                                    <li class="feature-not-enabled">
                                        Reference Capturing
                                    </li>
                                    <li class="feature-not-enabled">
                                        One-Off Content <sup>[1]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Head Content Injection <sup>[2]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Body Content Injection <sup>[3]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Render to IHtmlContent
                                    </li>
                                    <li class="feature-not-enabled">
                                        Render to String
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-md-3">
                        <div class="card bg-light border-danger h-100">
                            <div class="card-body">
                                <h4 class="card-title">
                                    Razor Component
                                </h4>
                                <ul class="feature-list">
                                    <li>
                                        Razor Syntax
                                    </li>
                                    <li>
                                        Nested Child Content
                                    </li>
                                    <li class="feature-not-enabled">
                                        Runtime Compilation
                                    </li>
                                    <li class="feature-not-enabled">
                                        MVC &amp; Razor Pages
                                    </li>
                                    <li class="feature-not-enabled">
                                        Lenient File Structure
                                    </li>
                                    <li>
                                        Named Slots
                                    </li>
                                    <li>
                                        Reference Capturing
                                    </li>
                                    <li class="feature-not-enabled">
                                        One-Off Content <sup>[1]</sup>
                                    </li>
                                    <li class="feature-partially-enabled">
                                        Head Content Injection <sup>[2]</sup>
                                    </li>
                                    <li class="feature-not-enabled">
                                        Body Content Injection <sup>[3]</sup>
                                    </li>
                                    <li>
                                        Render to IHtmlContent
                                    </li>
                                    <li>
                                        Render to String
                                    </li>
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>

                <section>

                    <p>
                        <strong class="d-block">
                            ✓ Feature Supported
                        </strong>
                        <strong class="d-block">
                            ◻ Feature Partially Supported
                        </strong>
                        <strong class="d-block">
                            ✕ Feature Not Supported
                        </strong>
                    </p>

                    <strong>[1] One-Off Content</strong>
                    <p>
                        Component content that is rendered only for the first instantiated component.
                    </p>

                    <strong>[2] Head Content Injection</strong>
                    <p>
                        Inject HTML content to the <code>head</code> tag from a component.
                    </p>

                    <strong>[3] Body Content Injection</strong>
                    <p>
                        Inject HTML content to the <code>body</code> tag from a component.
                    </p>
                </section>

                <section>
                    <h3>
                        Video Demonstration
                    </h3>

                    <div style="width: 100%; padding-top: 56.25%; position: relative;">
                        <iframe style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;" src="https://www.youtube.com/embed/T608th58dJM" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
                    </div>
                </section>

            </section>

            <section>
                <h2 class="scroll-anchor" id="examples">
                    Examples
                </h2>

                <p>
                    This section contains examples of how CshtmlComponents can be coded.
                </p>

                <section class="indent">
                    <h3 style="margin-top: 0">
                        Basic Example
                    </h3>

                    <p>
                        A basic CshtmlComponent that features <strong>attributes</strong> and <strong>child content</strong>.
                    </p>

                    <section class="indent">
                        <h4>
                            C# Code (ExampleComponent.cshtml.cs)
                        </h4>
                        <pre><code id="basic-example-code">using Acmion.CshtmlComponent;<br>using Microsoft.AspNetCore.Mvc;<br>using Microsoft.AspNetCore.Mvc.Rendering;<br>using Microsoft.AspNetCore.Razor.TagHelpers;<br>using System;<br>using System.Collections.Generic;<br>using System.Linq;<br>using System.Threading.Tasks;<br><br>namespace SampleRazorPagesApplication.Pages.Components.Example<br>{<br>    // The associated tag of the component.<br>    [HtmlTargetElement("ExampleComponent")]<br>    public class ExampleComponent : CshtmlComponentBase<br>    {<br>        // Explicitly named attribute.<br>        [HtmlAttributeName("Title")]<br>        public string Title { get; set; } = "";<br><br>        public ExampleComponent(IHtmlHelper htmlHelper) : base(htmlHelper)<br>        {<br>            // The constructor. <br>            // Note: Only dependency injected arguments.<br><br>            // This component resolves the name of the associated .cshtml file automatically. <br>            // The path to the .cshtml file must match the namespace and class name perfectly.<br><br>            // For this component the resolving logic is the following:<br>            //      Namespace = SampleRazorPagesApplication.Pages.Components.Example<br>            //      Class Name = ExampleComponent<br>            //<br>            //      1. Remove first part of namespace and replace dots with '/'. <br>            //      2. Append a '/'.<br>            //      3. Append Class Name.<br>            //      4. Append ".cshtml".<br>            //      <br>            //      Associated .cshtml file = /Pages/Components/Example/ExampleComponent.cshtml<br>        }<br>    }<br>}<br></code></pre>

                        <h4>
                            Cshtml Code (ExampleComponent.cshtml)
                        </h4>
                        <pre><code id="basic-example-cshtml-code">@* Reference the associated component as model. *@<br>@using SampleRazorPagesApplication.Pages.Components.Example<br>@model ExampleComponent<br><br>&lt;!-- The content of the component. --&gt;<br>&lt;div class="example-component" style="border: medium solid rgba(0, 0, 0, 0.1); padding: 1rem;"&gt;<br>    &lt;h1&gt;<br>        ExampleComponent: @Model.Title<br>    &lt;/h1&gt;<br><br>    &lt;div class="example-component-child-content"&gt;<br>        &lt;!-- Render the child content. --&gt;<br>        @Html.Raw(Model.ChildContent)<br>    &lt;/div&gt;<br>&lt;/div&gt;</code></pre>

                        <h4>
                            Component Instantiation
                        </h4>
                        <pre><code id="basic-example-instantiation-code">&lt;ExampleComponent Title="Some title"&gt;<br>    &lt;div&gt;<br>        Some custom HTML content.<br>        &lt;Box&gt;<br>            Supports nested components.<br>        &lt;/Box&gt;<br>    &lt;/div&gt;<br>&lt;/ExampleComponent&gt;</code></pre>
                    </section>

                </section>

                <section class="indent">
                    <h3 style="margin-top: 0">
                        Advanced Example
                    </h3>

                    <p>
                        An advanced CshtmlComponent that features <strong>attributes</strong>, <strong>child content</strong>,
                        <strong>named slots</strong>, <strong>typed slots</strong>, <strong>reference capturing</strong>,
                        <strong>head content injection</strong>, <strong>body content injection</strong>,
                        <strong>one-off content</strong> and <strong>model mutation</strong>.
                    </p>

                    <section class="indent">
                        <h4>
                            C# Code (AdvancedExampleComponent.cshtml.cs)
                        </h4>
                        <pre><code id="advanced-example-code">using Acmion.CshtmlComponent;<br>using Microsoft.AspNetCore.Mvc;<br>using Microsoft.AspNetCore.Mvc.Rendering;<br>using Microsoft.AspNetCore.Razor.TagHelpers;<br>using System;<br>using System.Collections.Generic;<br>using System.Linq;<br>using System.Threading.Tasks;<br><br>namespace SampleRazorPagesApplication.Pages.Components.Example<br>{<br>    // The associated tag of the component.<br>    [HtmlTargetElement("AdvancedExampleComponent")]<br>    public class AdvancedExampleComponent : CshtmlComponentBase<br>    {<br>        // Explicitly named attribute.<br>        [HtmlAttributeName("Title")]<br>        public string Title { get; set; } = "";<br><br>        // These properties will default to their kebab-cased variants.<br>        public string FontSize { get; set; } = "1rem";<br>        public string BackgroundColor { get; set; } = "rgba(255, 0, 0, 0.1)";<br><br>        // A not HTML bound property, which can not be accessed as a attribute in the component tag.<br>        [HtmlAttributeNotBound]<br>        public string UppercaseTitle { get; set; } = "";<br><br>        public AdvancedExampleComponent(IHtmlHelper htmlHelper) : base(htmlHelper, "/Pages/Components/Example/AdvancedExampleComponent.cshtml", "div", TagMode.StartTagAndEndTag)<br>        {<br>            // The constructor. <br>            // Note: Only dependency injected arguments.<br><br>            // "/Pages/Components/Example/AdvancedExampleComponent.cshtml" is the path to the associated .cshtml file.<br>            // "div" is the output tag name. Defaults to null.<br>            // TagMode.StartTagAndEndTag determines the tag structure, optional parameter. Defaults to TagMode.StartTagAndEndTag.<br><br>            // Properties should not be accessed here, because they will not yet be set.<br>        }<br><br>        protected override Task ProcessComponent(TagHelperContext context, TagHelperOutput output)<br>        {<br>            // This method is called just before the associated .cshtml file is executed.<br>            // Properties have been initialized and can be accessed.<br><br>            // The property ChildContent is a string that contains the child content.<br><br>            // Use this method to edit some other properties or fields.<br><br>            UppercaseTitle = Title.ToUpperInvariant();<br><br>            return base.ProcessComponent(context, output);<br>        }<br>    }<br>}<br></code></pre>

                        <h4>
                            Cshtml Code (AdvancedExampleComponent.cshtml)
                        </h4>
                        <pre><code id="advanced-example-cshtml-code">@* Reference the associated component as model. *@<br>@using SampleRazorPagesApplication.Pages.Components.Example<br>@model AdvancedExampleComponent<br><br>&lt;!-- Content that is injected in to the &lt;head&gt; tag. --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;CshtmlHead&gt;<br>    &lt;!-- This content will be appended to &lt;head&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlHead, Key: default, ContentOrder: default" /&gt;<br>    &lt;link rel="stylesheet" href="~/css/advanced-example-component.css" /&gt;<br>    &lt;script&gt;console.log("CshtmlHead, Key: default, ContentOrder: default");&lt;/script&gt;<br>&lt;/CshtmlHead&gt;<br><br>&lt;CshtmlHead&gt;<br>    &lt;!-- This content will NOT be appended to &lt;head&gt;, because the default key is already used. --&gt;<br>    &lt;meta name="description" content="CshtmlHead, Key: default, ContentOrder: default" /&gt;<br>    &lt;script&gt;console.log("CshtmlHead, Key: default, ContentOrder: default");&lt;/script&gt;<br>&lt;/CshtmlHead&gt;<br><br>&lt;CshtmlHead Key="0" ContentOrder="0"&gt;<br>    &lt;!-- This content will be appended to &lt;head&gt; and will appear before &lt;CshtmlHead&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlHead, Key: default, ContentOrder: 0" /&gt;<br>    &lt;script&gt;console.log("CshtmlHead, Key: default, ContentOrder: 0");&lt;/script&gt;<br>&lt;/CshtmlHead&gt;<br><br>&lt;CshtmlHead Key="-1" ContentOrder="-1"&gt;<br>    &lt;!-- This content will be prepended to &lt;head&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlHead, Key: -1, ContentOrder: -1" /&gt;<br>    &lt;script&gt;console.log("CshtmlHead, Key: -1, ContentOrder: -1");&lt;/script&gt;<br>&lt;/CshtmlHead&gt;<br><br>&lt;CshtmlHead Multiple="true" ContentOrder="-2"&gt;<br>    &lt;!-- This content will be prepended to &lt;head&gt; and will appear before &lt;CshtmlHead ContentOrder="-1"&gt;, every time this component is instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlHead, Multiple: true, ContentOrder: -2" /&gt;<br>    &lt;script&gt;console.log("CshtmlHead, Multiple: true, ContentOrder: -2");&lt;/script&gt;<br>&lt;/CshtmlHead&gt;<br><br><br><br><br>&lt;!-- Content that is injected in to the &lt;body&gt; tag. --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;!-- ---------------------------------------------- --&gt;<br>&lt;CshtmlBody&gt;<br>    &lt;!-- This content will be appended to &lt;body&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlBody, Key: default, ContentOrder: default" /&gt;<br>    &lt;script&gt;console.log("CshtmlBody, Key: default, ContentOrder: default");&lt;/script&gt;<br>&lt;/CshtmlBody&gt;<br><br>&lt;CshtmlBody&gt;<br>    &lt;!-- This content will NOT be appended to &lt;body&gt;, because the default key is already used. --&gt;<br>    &lt;meta name="description" content="CshtmlBody, Key: default, ContentOrder: default" /&gt;<br>    &lt;script&gt;console.log("CshtmlBody, Key: default, ContentOrder: default");&lt;/script&gt;<br>&lt;/CshtmlBody&gt;<br><br>&lt;CshtmlBody Key="0" ContentOrder="0"&gt;<br>    &lt;!-- This content will be appended to &lt;body&gt; and will appear before &lt;CshtmlBody&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlBody, Key: default, ContentOrder: 0" /&gt;<br>    &lt;script&gt;console.log("CshtmlBody, Key: default, ContentOrder: 0");&lt;/script&gt;<br>&lt;/CshtmlBody&gt;<br><br>&lt;CshtmlBody Key="-1" ContentOrder="-1"&gt;<br>    &lt;!-- This content will be prepended to &lt;body&gt;, when this component is first instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlBody, Key: -1, ContentOrder: -1" /&gt;<br>    &lt;script&gt;console.log("CshtmlBody, Key: -1, ContentOrder: -1");&lt;/script&gt;<br>&lt;/CshtmlBody&gt;<br><br>&lt;CshtmlBody Multiple="true" ContentOrder="-2"&gt;<br>    &lt;!-- This content will be prepended to &lt;body&gt; and will appear before &lt;CshtmlBody ContentOrder="-1"&gt;, every time this component is instantiated. --&gt;<br>    &lt;meta name="description" content="CshtmlBody, Multiple: true, ContentOrder: -2" /&gt;<br>    &lt;script&gt;console.log("CshtmlBody, Multiple: true, ContentOrder: -2");&lt;/script&gt;<br>&lt;/CshtmlBody&gt;<br><br><br><br><br>&lt;!-- One off content that is rendered as is and wherever this component is instantiated. --&gt;<br>&lt;!-- ----------------------------------------------------------------------------------- --&gt;<br>&lt;!-- ----------------------------------------------------------------------------------- --&gt;<br>&lt;!-- ----------------------------------------------------------------------------------- --&gt;<br>&lt;CshtmlInitial&gt;<br>    &lt;!-- This content will be rendered, as is, wherever this component is first instantiated. --&gt;<br>    &lt;script&gt;console.log("CshtmlInitial, Key: default");&lt;/script&gt;<br>&lt;/CshtmlInitial&gt;<br><br>&lt;CshtmlInitial&gt;<br>    &lt;!-- This content will NOT be rendered, because the default key is already used. --&gt;<br>    &lt;script&gt;console.log("CshtmlInitial, Key: default 2");&lt;/script&gt;<br>&lt;/CshtmlInitial&gt;<br><br>&lt;CshtmlInitial Key="I1"&gt;<br>    &lt;!-- Explicitly keyed. This content will be rendered, as is, wherever this component is first instantiated. --&gt;<br>    &lt;script&gt;console.log("CshtmlInitial, Key: I1");&lt;/script&gt;<br>    @{ <br>        var a = 0;<br>    }<br>&lt;/CshtmlInitial&gt;<br><br><br><br><br>&lt;!-- The actual content of this component. --&gt;<br>&lt;!-- ------------------------------------- --&gt;<br>&lt;!-- ------------------------------------- --&gt;<br>&lt;!-- ------------------------------------- --&gt;<br>&lt;div class="advanced-example-component" style="background-color: @Model.BackgroundColor; font-size: @Model.FontSize"&gt;<br>    @{<br>        // Assign a variable to a component reference.<br>        // The Box component inherits CshtmlComponentReferenceableBase&lt;Box&gt; (a class that inherits CshtmlComponentBase),<br>        // which implements this logic. Useful if component properties have to be used outside the component's own context.<br><br>        // This is not the default behavior due to the mandatory, but slightly weird syntax:<br>        // public Box : CshtmlComponentReferenceableBase&lt;Box&gt; ....<br><br>        // See the source code of Pages/Components/Box.cshtml.cs for how the component class looks like.<br><br>        var boxReference = new CshtmlComponentReference&lt;Box&gt;();<br><br>        &lt;Box Reference="boxReference"&gt;<br>            &lt;h1&gt;<br>                AdvancedExampleComponent: @Model.UppercaseTitle<br>            &lt;/h1&gt;<br>            &lt;p&gt;<br>                The fontsize of the referenced Box is: @boxReference.Component.FontSize <br>            &lt;/p&gt;<br>        &lt;/Box&gt;<br>    }<br><br>    &lt;br /&gt;<br><br>    &lt;div class="advanced-example-component-slot0"&gt;<br>        &lt;!-- Render a named slot. --&gt;<br>        @Html.Raw(Model.NamedSlots["SlotName0"])<br>    &lt;/div&gt;<br><br>    &lt;br /&gt;<br><br>    &lt;div class="advanced-example-component-child-content"&gt;<br>        &lt;!-- Render the child content. --&gt;<br>        @Html.Raw(Model.ChildContent)<br>    &lt;/div&gt;<br><br>    &lt;br /&gt;<br><br>    &lt;div class="advanced-example-component-slot1"&gt;<br>        &lt;!-- Render a typed (or named) slot. --&gt;<br>        @Html.Raw(Model.NamedSlots[AdvancedExampleComponentTypedSlot.SlotName])<br>    &lt;/div&gt;<br><br>    &lt;br /&gt;<br><br>    &lt;div class="advanced-example-component-manual-render"&gt;<br>        &lt;!-- Manually render a component. Note the constructor argument and that some properties have to be manually set. --&gt;<br>        @{<br>            var manualBox = new Box(Html) { ChildContent = "Manually rendered box" };<br>        }<br><br>        @await manualBox.RenderAsync()<br><br>        &lt;br /&gt;<br><br>        &lt;!-- The content can also be rendered into a string. May be useful if templates must be passed to, for example, JavaScript. --&gt;<br>        @{ <br>            var manualBoxRenderedToString = await manualBox.RenderToStringAsync(preserveLineBreaks: false);<br>        }<br><br>        @Html.Raw(manualBoxRenderedToString)<br>    &lt;/div&gt;<br>&lt;/div&gt;<br></code></pre>

                        <h4>
                            Component Instantiation
                        </h4>
                        <pre><code id="advanced-example-instantiation-code">&lt;AdvancedExampleComponent Title="Some title" font-size="1.2rem" background-color="rgba(0, 0, 255, 0.1)"&gt;<br>    &lt;div&gt;<br>        Some custom HTML content.<br>        &lt;Box&gt;<br>            Supports nested components.<br>        &lt;/Box&gt;<br>    &lt;/div&gt;<br>    &lt;CshtmlSlot Name="SlotName0"&gt;<br>        Some custom HTML content within a named slot. The parent component decides where<br>        this content is placed.<br>    &lt;/CshtmlSlot&gt;<br>    &lt;AdvancedExampleComponentTypedSlot&gt;<br>        Additional custom HTML content within a &lt;strong&gt;typed&lt;/strong&gt; slot.<br>        See the source code of &lt;code&gt;/Pages/Components/Example/AdvancedExampleComponentTypesSlot.cs&lt;/code&gt;.<br>        &lt;Box&gt;<br>            Supports nested components.<br>        &lt;/Box&gt;<br>    &lt;/AdvancedExampleComponentTypedSlot&gt;<br>&lt;/AdvancedExampleComponent&gt;</code></pre>
                    </section>

                </section>


            </section>

            <section>
                <h2 class="scroll-anchor" id="core">
                    Core
                </h2>

                <p>
                    This section documents the main built in classes and components of CshtmlComponent.
                </p>

                <section class="indent">
                    <h3>CshtmlComponentBase</h3>
                    <p>
                        <code>CshtmlComponentBase</code> is the base class which all components should inherit.
                        The class inherits <code>TagHelper</code> and all of its functionality.
                        See the documentation for <code>TagHelper</code>
                        <a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro?view=aspnetcore-3.1">here</a>.
                    </p>

                    <section class="indent">
                        <h4>
                            Properties
                        </h4>

                        <p>
                            The properties of <code>CshtmlComponentBase</code> (not including inherited).
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                HtmlHelper
                            </h5>

                            <p>
                                <strong>Type</strong>: IHtmlHelper
                            </p>
                            <p>
                                <strong>Default Value</strong>: [Dependency Injected in Constructor]
                            </p>
                            <p>
                                <strong>Description</strong>: The IHtmlHelper the component was initialized by.
                                Generally, dependency injected by ASP.NET Core.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                ViewContext
                            </h5>

                            <p>
                                <strong>Type</strong>: ViewContext
                            </p>
                            <p>
                                <strong>Default Value</strong>: [Auto Generated]
                            </p>
                            <p>
                                <strong>Description</strong>: The current ViewContext. Automatically set by ASP.NET Core.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                PartialViewName
                            </h5>

                            <p>
                                <strong>Type</strong>: string?
                            </p>
                            <p>
                                <strong>Default Value</strong>: null
                            </p>
                            <p>
                                <strong>Description</strong>: The path to the associated .cshtml file. The contents of this file will
                                be rendered.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                OutputTagName
                            </h5>

                            <p>
                                <strong>Type</strong>: string?
                            </p>
                            <p>
                                <strong>Default Value</strong>: null
                            </p>
                            <p>
                                <strong>Description</strong>: Describes within which tag the component output should be wrapped. Default value null
                                means that no extra wrapping component is created.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                OutputTagMode
                            </h5>

                            <p>
                                <strong>Type</strong>: TagMode
                            </p>
                            <p>
                                <strong>Default Value</strong>: TagMode.StartTagAndEndTag
                            </p>
                            <p>
                                <strong>Description</strong>: Describes how the resulting component should be closed. Mainly related to the optional OutputTagName.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                ChildContent
                            </h5>

                            <p>
                                <strong>Type</strong>: string
                            </p>
                            <p>
                                <strong>Default Value</strong>: [Auto Generated]
                            </p>
                            <p>
                                <strong>Description</strong>: The child content of the component.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                NamedSlots
                            </h5>

                            <p>
                                <strong>Type</strong>: Dictionary&lt;string, string&gt;
                            </p>
                            <p>
                                <strong>Default Value</strong>: [Empty Dictionary]
                            </p>
                            <p>
                                <strong>Description</strong>: The content of the optional named slots.
                            </p>
                        </section>
                    </section>

                    <section class="indent">
                        <h4>
                            Constructors
                        </h4>

                        <p>
                            The constructors of <code>CshtmlComponentBase</code>, their arguments and the key properties that they set.
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                public CshtmlComponentBase(IHtmlHelper htmlHelper)
                            </h5>

                            <p>
                                <strong>HtmlHelper</strong>: htmlHelper
                            </p>
                            <p>
                                <strong>PartialViewName</strong>: The path to the associated .cshtml file is auto generated by analyzing the namespace
                                and the class name of the component. For example, if the namespace is "SampleRazorPagesApplication.Pages.Components.Example"
                                and the class name is "ExampleComponent", then PartialViewName will be "/Pages/Components/Example/ExampleComponent.cshtml".
                            </p>
                            <p>
                                <strong>OutputTagName</strong>: null
                            </p>
                            <p>
                                <strong>OutputTagMode</strong>: TagMode.StartTagAndEndTag
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public CshtmlComponentBase(IHtmlHelper htmlHelper, string? partialViewName)
                            </h5>

                            <p>
                                <strong>HtmlHelper</strong>: htmlHelper
                            </p>
                            <p>
                                <strong>PartialViewName</strong>: partialViewName
                            </p>
                            <p>
                                <strong>OutputTagName</strong>: null
                            </p>
                            <p>
                                <strong>OutputTagMode</strong>: TagMode.StartTagAndEndTag
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public CshtmlComponentBase(IHtmlHelper htmlHelper, string? partialViewName, string? outputTagName = null)
                            </h5>

                            <p>
                                <strong>HtmlHelper</strong>: htmlHelper
                            </p>
                            <p>
                                <strong>OutputTagName</strong>: outputTagName
                            </p>
                            <p>
                                <strong>OutputTagMode</strong>: TagMode.StartTagAndEndTag
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public CshtmlComponentBase(IHtmlHIHtmlHelper htmlHelper, string? partialViewName, string? outputTagName = null, TagMode outputTagMode = TagMode.StartTagAndEndTag)
                            </h5>

                            <p>
                                <strong>HtmlHelper</strong>: htmlHelper
                            </p>
                            <p>
                                <strong>PartialViewName</strong>: partialViewName
                            </p>
                            <p>
                                <strong>OutputTagName</strong>: outputTagName
                            </p>
                            <p>
                                <strong>OutputTagMode</strong>: outputTagMode
                            </p>
                        </section>

                    </section>

                    <section class="indent">
                        <h4>
                            Methods
                        </h4>

                        <p>
                            The methods of <code>CshtmlComponentBase</code> and what they do and return (not including inherited).
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                public IHtmlContent Render()
                            </h5>

                            <p>
                                Renders and returns the content of the component.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public Task&lt;IHtmlContent&gt; RenderAsync()
                            </h5>

                            <p>
                                Renders and returns the content of the component asynchronously.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public string RenderToString(bool preserveLineBreaks = true)
                            </h5>

                            <p>
                                Renders and returns the content of the component.
                                If <code>preserveLineBreaks = true</code>, then line breaks are preserved, otherwise they are not.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                public async Task&lt;string&gt; RenderToStringAsync(bool preserveLineBreaks = true)
                            </h5>

                            <p>
                                Renders and returns the content of the component asynchronously.
                                If <code>preserveLineBreaks = true</code>, then line breaks are preserved, otherwise they are not.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                protected virtual Task ProcessComponent(TagHelperContext context, TagHelperOutput output)
                            </h5>

                            <p>
                                A method that is executed just before a component is rendered.
                                By default the method does nothing, but by overriding it you may control properties and other
                                things. Properties may generally not be controlled in the constructor, due to the fact
                                that they may not be initialized. When this method is called, all properties that have explicitly
                                been defined will have been set. Note that CshtmlComponent does not differentiate between required
                                and non-required properties. Ff this is important for you, then you should implement checking logic
                                here.
                            </p>
                        </section>
                    </section>
                </section>

                <section class="indent">
                    <h3>CshtmlComponentReferenceableBase&lt;ReferencableComponentType&gt;</h3>
                    <p>
                        <code>CshtmlComponentReferenceableBase</code> is the base class which components that
                        require reference capturing should inherit. This is not the default behavior due to the
                        slightly unorthodox inheritance syntax. For example, if you define the component "Box",
                        then in the class declaration you must use this syntax:
                    </p>
                    <pre><code>public class Box : CshtmlComponentReferenceableBase&lt;Box&gt;</code></pre>
                    The class inherits <code>CshtmlComponentBase</code> and all of its functionality.
                    <p></p>

                    <section class="indent">
                        <h4>
                            Properties
                        </h4>

                        <p>
                            The properties of <code>CshtmlComponentReferenceableBase&lt;ReferencableComponentType&gt;</code> (not including inherited).
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                Reference
                            </h5>

                            <p>
                                <strong>Type</strong>: CshtmlComponentReferenceableBase&lt;ReferencableComponentType&gt;
                            </p>
                            <p>
                                <strong>Default Value</strong>: null
                            </p>
                            <p>
                                <strong>Description</strong>: A property that allows you to capture the reference to a component from a .cshtml file.
                                Useful if, for example, one must access an id that another component defines. See the Advanced Example for how to accomplish
                                this.
                            </p>
                        </section>
                    </section>

                    <section class="indent">
                        <h4>
                            Constructors
                        </h4>

                        <p>
                            The constructors of <code>CshtmlComponentReferenceableBase&lt;ReferencableComponentType&gt;</code> are exactly the same as those of
                            <code>CshtmlComponentBase</code>.
                        </p>
                    </section>
                </section>

                <section class="indent">
                    <h3>CshtmlHead</h3>
                    <p>
                        <code>CshtmlHead</code> allows one to inject content in to the <code>head</code> tag of a document. By default,
                        only one <code>CshtmlHead</code> tag is supported per component, but this can be overridden with the use of attributes.
                        Note that instantiating multiple components of the same type will not render the content of a <code>CshtmlHead</code> tag
                        multiple times, unless explicitly specified.
                    </p>

                    <section class="indent">
                        <h4>
                            Attributes
                        </h4>

                        <p>
                            The attributes of <code>CshtmlHead</code>.
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                Key
                            </h5>

                            <p>
                                <strong>Type</strong>: string
                            </p>
                            <p>
                                <strong>Default Value</strong>: ""
                            </p>
                            <p>
                                <strong>Description</strong>: Sets a key for the tag. Multiple <code>CshtmlHead</code> tags with unique keys are supported per component.
                                Only the first <code>CshtmlHead</code> tag with a unique key is rendered (within the context of a component).
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                Multiple
                            </h5>

                            <p>
                                <strong>Type</strong>: bool
                            </p>
                            <p>
                                <strong>Default Value</strong>: false
                            </p>
                            <p>
                                <strong>Description</strong>: If true, then renders the content of a <code>CshtmlHead</code> tag, even if the key is not unique. Additionally,
                                if true, then instantiating multiple components of the same type in a request will render the content of a <code>CshtmlHead</code> tag multiple
                                times. This feature should almost never be used.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                ContentOrder
                            </h5>

                            <p>
                                <strong>Type</strong>: int
                            </p>
                            <p>
                                <strong>Default Value</strong>: int.MaxValue
                            </p>
                            <p>
                                <strong>Description</strong>: Sets the order of <code>CshtmlHead</code> tags. The content of <code>CshtmlHead</code> tags
                                with negative values are prepended to the document <code>head</code> element, so that the most negative ones are rendered first.
                                The content of <code>CshtmlHead</code> tags with positive values (including zero) are appended to the document <code>head</code>
                                element, so that the least positive ones are rendered first. The default behavior will append everything to the <code>head</code>
                                element. Useful if certain components require, for example, the JS of other components. One component should in most cases
                                use only one ContentOrder.
                            </p>
                        </section>
                    </section>

                    <section class="indent">
                        <h4>
                            CshtmlHead Ordering Example
                        </h4>

                        <p>
                            An example that shows how <code>CshtmlHead</code> affects the content of the <code>head</code> element.
                        </p>

                        <pre><code id="cshtml-head-ordering-example-code">&lt;!DOCTYPE html&gt;<br>&lt;html&gt;<br>    &lt;head&gt;<br>        &lt;!-- <br>            &lt;CshtmlHead ContentOrder="int.MinValue"&gt; content here.  <br>            &lt;CshtmlHead ContentOrder="int.MinValue + 1"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="int.MinValue + 2"&gt; content here.<br>            ...<br>            &lt;CshtmlHead ContentOrder="-999"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="-998"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="-997"&gt; content here.<br>            ...<br>            &lt;CshtmlHead ContentOrder="-3"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="-2"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="-1"&gt; content here.<br>        --&gt;<br><br>        &lt;!--<br>            Standard &lt;head&gt; content here. Often specified in a _layout.cshtml file.<br>        --&gt;<br><br>        &lt;!--<br>            &lt;CshtmlHead ContentOrder="0"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="1"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="2"&gt; content here.<br>            ...<br>            &lt;CshtmlHead ContentOrder="997"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="998"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="999"&gt; content here.<br>            ...<br>            &lt;CshtmlHead ContentOrder="int.MaxValue - 2"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="int.MaxValue - 1"&gt; content here.<br>            &lt;CshtmlHead ContentOrder="int.MaxValue"&gt; content here. Default location.<br>        --&gt;<br>    &lt;/head&gt;<br>    &lt;body&gt;<br>        &lt;!-- Some content here. --&gt;<br>    &lt;/body&gt;<br>&lt;/html&gt;</code></pre>
                    </section>
                </section>

                <section class="indent">
                    <h3>CshtmlBody</h3>
                    <p>
                        <code>CshtmlBody</code> allows one to inject content in to the <code>body</code> tag of a document. By default,
                        only one <code>CshtmlBody</code> tag is supported per component, but this can be overridden with the use of attributes.
                        Note that instantiating multiple components of the same type will not render the content of a <code>CshtmlBody</code> tag
                        multiple times, unless explicitly specified.
                    </p>

                    <section class="indent">
                        <h4>
                            Attributes
                        </h4>

                        <p>
                            The attributes of <code>CshtmlBody</code>.
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                Key
                            </h5>

                            <p>
                                <strong>Type</strong>: string
                            </p>
                            <p>
                                <strong>Default Value</strong>: ""
                            </p>
                            <p>
                                <strong>Description</strong>: Sets a key for the tag. Multiple <code>CshtmlBody</code> tags with unique keys are supported per component.
                                Only the first <code>CshtmlBody</code> tag with a unique key is rendered (within the context of a component).
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                Multiple
                            </h5>

                            <p>
                                <strong>Type</strong>: bool
                            </p>
                            <p>
                                <strong>Default Value</strong>: false
                            </p>
                            <p>
                                <strong>Description</strong>: If true, then renders the content of a <code>CshtmlBody</code> tag, even if the key is not unique. Additionally,
                                if true, then instantiating multiple components of the same type in a request will render the content of a <code>CshtmlBody</code> tag multiple
                                times. This feature should almost never be used.
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                ContentOrder
                            </h5>

                            <p>
                                <strong>Type</strong>: int
                            </p>
                            <p>
                                <strong>Default Value</strong>: int.MaxValue
                            </p>
                            <p>
                                <strong>Description</strong>: Sets the order of <code>CshtmlBody</code> tags. The content of <code>CshtmlBody</code> tags
                                with negative values are prepended to the document <code>body</code> element, so that the most negative ones are rendered first.
                                The content of <code>CshtmlBody</code> tags with positive values (including zero) are appended to the document <code>body</code>
                                element, so that the least positive ones are rendered first. The default behavior will append everything to the <code>body</code>
                                element. Useful if certain components require, for example, the JS of other components. One component should in most cases
                                use only one ContentOrder.
                            </p>
                        </section>
                    </section>

                    <section class="indent">
                        <h4>
                            CshtmlBody Ordering Example
                        </h4>

                        <p>
                            An example that shows how <code>CshtmlBody</code> affects the content of the <code>head</code> element.
                        </p>

                        <pre><code id="cshtml-body-ordering-example-code">&lt;!DOCTYPE html&gt;<br>&lt;html&gt;<br>    &lt;head&gt;<br>        &lt;!-- Some content here. --&gt;<br>    &lt;/head&gt;<br>    &lt;body&gt;<br>        &lt;!-- <br>            &lt;CshtmlBody ContentOrder="int.MinValue"&gt; content here.  <br>            &lt;CshtmlBody ContentOrder="int.MinValue + 1"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="int.MinValue + 2"&gt; content here.<br>            ...<br>            &lt;CshtmlBody ContentOrder="-999"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="-998"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="-997"&gt; content here.<br>            ...<br>            &lt;CshtmlBody ContentOrder="-3"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="-2"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="-1"&gt; content here.<br>        --&gt;<br><br>        &lt;!--<br>            Standard &lt;body&gt; content here.<br>        --&gt;<br><br>        &lt;!--<br>            &lt;CshtmlBody ContentOrder="0"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="1"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="2"&gt; content here.<br>            ...<br>            &lt;CshtmlBody ContentOrder="997"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="998"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="999"&gt; content here.<br>            ...<br>            &lt;CshtmlBody ContentOrder="int.MaxValue - 2"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="int.MaxValue - 1"&gt; content here.<br>            &lt;CshtmlBody ContentOrder="int.MaxValue"&gt; content here. Default location.<br>        --&gt;<br>    &lt;/body&gt;<br>&lt;/html&gt;</code></pre>
                    </section>
                </section>

                <section class="indent">
                    <h3>CshtmlInitial</h3>
                    <p>
                        <code>CshtmlInitial</code> allows one to inject one-off content in to a component. By default,
                        only one <code>CshtmlInitial</code> tag is supported per component, but this can be overridden with the use of attributes.
                        Note that instantiating multiple components of the same type will not render the content of a <code>CshtmlInitial</code> tag
                        multiple times, unless explicitly specified.
                    </p>

                    <section class="indent">
                        <h4>
                            Attributes
                        </h4>

                        <p>
                            The attributes of <code>CshtmlInitial</code>.
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                Key
                            </h5>

                            <p>
                                <strong>Type</strong>: string
                            </p>
                            <p>
                                <strong>Default Value</strong>: ""
                            </p>
                            <p>
                                <strong>Description</strong>: Sets a key for the tag. Multiple <code>CshtmlInitial</code> tags with unique keys are supported per component.
                                Only the first <code>CshtmlInitial</code> tag with a unique key is rendered (within the context of a component).
                            </p>
                        </section>

                        <section class="indent p-no-margin">
                            <h5>
                                Multiple
                            </h5>

                            <p>
                                <strong>Type</strong>: bool
                            </p>
                            <p>
                                <strong>Default Value</strong>: false
                            </p>
                            <p>
                                <strong>Description</strong>: If true, then renders the content of a <code>CshtmlInitial</code> tag, even if the key is not unique. Additionally,
                                if true, then instantiating multiple components of the same type in a request will render the content of a <code>CshtmlInitial</code> tag multiple
                                times. This feature should almost never be used.
                            </p>
                        </section>
                    </section>
                </section>

                <section class="indent">
                    <h3>CshtmlSlot</h3>
                    <p>
                        <code>CshtmlSlot</code> allows one to specify named slots. The parent component then
                        decides where this content is rendered. Can be inherited to create typed slots. Typed slots
                        do not require the specification of the Name attribute, which improves maintenance.
                    </p>

                    <section class="indent">
                        <h4>
                            Attributes
                        </h4>

                        <p>
                            The attributes of <code>CshtmlSlot</code>.
                        </p>

                        <section class="indent p-no-margin">
                            <h5>
                                Name
                            </h5>

                            <p>
                                <strong>Type</strong>: string
                            </p>
                            <p>
                                <strong>Default Value</strong>: ""
                            </p>
                            <p>
                                <strong>Description</strong>: The name of the slot. The content of the slot is stored in a dictionary, where
                                Name is the key. Components that implement slots, should then render this content in an appropriate place.
                            </p>
                        </section>
                    </section>
                </section>

            </section>

            <section>
                <h2 class="scroll-anchor" id="usage">
                    Usage
                </h2>

                <p>
                    This section documents how <strong>CshtmlComponent</strong> should be installed and how to author custom components.
                </p>

                <section class="indent">
                    <h3>
                        Installation &amp; Initialization
                    </h3>
                    <p>
                    </p>
                    <ol>
                        <li>
                            Install the <a href="https://www.nuget.org/packages/Acmion.CshtmlComponent/">Nuget package</a>.
                        </li>
                        <li>
                            Dependency inject some classes in <code>Startup.cs</code>:
                            <pre><code id="dependency-injection-code">public void ConfigureServices(IServiceCollection services)<br>{<br>    // Some other configuration here.<br><br>    services.AddScoped&lt;ICshtmlComponentTracker, CshtmlComponentTracker&gt;();<br>    services.AddScoped&lt;ITagHelperComponent, CshtmlComponentInjectionContentHandler&gt;();<br>    services.AddScoped&lt;ICshtmlComponentInjectionContentStore, CshtmlComponentInjectionContentStore&gt;();<br><br>    // Some other configuration here.<br>}</code></pre>
                        </li>
                        <li>
                            In an appropriate <code>_ViewImports.cshtml</code> (usually located directly under the <code>Pages</code>
                            directory) add the following:
                            <pre><code id="view-imports-code">// Built in CshtmlComponent components.<br>@addTagHelper *, Acmion.CshtmlComponent<br><br>// Components defined in your project.<br>@addTagHelper *, YourProjectName<br></code></pre>
                        </li>
                    </ol>
                    <p></p>
                </section>

                <section class="indent">
                    <h3>
                        Authoring Custom CshtmlComponents
                    </h3>
                    <p>
                    </p>
                    <ol>
                        <li>
                            Create the file <code>ExampleComponent.cshtml.cs</code> somewhere under your ASP.NET Core Project (usually
                            under the <code>Pages</code> or <code>View</code> directory, but anything should work).
                        </li>
                        <li>
                            Create the file <code>ExampleComponent.cshtml</code> in the same location.
                        </li>
                        <li>
                            In <code>ExampleComponent.cs</code>:
                            <ol>
                                <li>
                                    Inherit <code>CshtmlComponentBase</code>. If you want to capture the reference to this component, then you
                                    should instead inherit <code>CshtmlComponentReferenceableBase&lt;ExampleComponent&gt;</code>. No other changes
                                    necessary.
                                </li>
                                <li>
                                    Implement one of the constructor so that all arguments are dependency injected arguments. In most cases,
                                    it is enough that <code>IHtmlHelper htmlHelper</code> is the only argument.
                                </li>
                                <li>
                                    Add <code>[HtmlTargetElement("ExampleComponentTag")]</code> to the component class, where
                                    <code>ExampleComponentTag</code> is the tag that the component will be associated with.
                                </li>
                                <li>
                                    Optionally, specify how the tag should be closed in <code>HtmlTargetElement</code>, see more about how this
                                    is achieved in the <a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring">TagHelper docs</a>.
                                </li>
                                <li>
                                    List all component attributes as C# properties. ASP.NET Core will translate the properties to their kebabcased
                                    variants, unless otherwise specified with <code>[HtmlAttributeName("AttributeName")]</code>, where
                                    <code>AttributeName</code> is the name of the attribute.
                                </li>
                                <li>
                                    Create fields or properties for all other values you wish to use in <code>ExampleComponent.cshtml</code>.
                                </li>
                                <li>
                                    Optionally, override <code>protected virtual Task ProcessComponent()</code>, which is called before
                                    <code>ExampleComponent.cshtml</code> is executed. Here you can extract information from properties and
                                    access other fields etc. This can not be done in the constructor, since any provided properties
                                    will not have been set yet. The nested child content can be accessed in this method by accessing
                                    <code>ChildContent</code>. The named slots can be accessed by accessing <code>NamedSlots</code>
                                </li>
                            </ol>
                        </li>
                        <li>
                            In <code>ExampleComponent.cshtml</code>:
                            <ol>
                                <li>
                                    Set the model to <code>ExampleComponent</code> with <code>@model ExampleComponent</code>. You may need to
                                    add appropriate using statements.
                                </li>
                                <li>
                                    Component properties and field are accessible with <code>Model.PropertyName</code>.
                                </li>
                                <li>
                                    The nested child content can be accessed with <code>Model.ChildContent</code>. To render the child content,
                                    you can use <code>Html.Raw(Model.ChildContent)</code>, but note that this does not encode the HTML, which means
                                    that XSS attacks are possible if non-validated user input is used as child content.
                                </li>
                                <li>
                                    Any named slots can be accessed with <code>Model.NamedSlots</code>. To render the slot content,
                                    you can use <code>Html.Raw(Model.NamedSlots["SlotName"])</code>, but note that this does not encode the HTML, which means
                                    that XSS attacks are possible if non-validated user input is used as child content. The named slots have to be defined, in
                                    the initializing context, with <code>&lt;CshtmlSlot Name="SlotName"&gt;[CONTENT HERE]&lt;CshtmlSlot&gt;</code> or by using
                                    typed slots. See the advanced example in <a href="#examples">Examples</a>.
                                </li>
                                <li>
                                    Use <code>&lt;CshtmlHead&gt;[CONTENT HERE]&lt;CshtmlHead&gt;</code>,
                                    <code>&lt;CshtmlBody&gt;[CONTENT HERE]&lt;CshtmlBody&gt;</code> and
                                    <code>&lt;CshtmlInitial&gt;[CONTENT HERE]&lt;CshtmlInitial&gt;</code>
                                    to render or inject content according to the rules in <a href="#components">Components</a>.
                                </li>
                                <li>
                                    Render your markup and use <code>.cshtml</code> files as you wish.
                                </li>
                            </ol>
                        </li>
                    </ol>
                    <p></p>
                </section>

                <section class="indent">
                    <h3>
                        Notes
                    </h3>
                    <p>
                    </p>
                    <ul>
                        <li>
                            See the sample project in the <a href="https://github.com/Acmion/CshtmlComponent.git">CshtmlComponent GitHub repository</a> for concrete
                            examples.
                        </li>
                        <li>
                            A CshtmlComponent is just a TagHelper with some "magic". In practice, everything that applies to
                            ASP.NET Core TagHelpers apply to CshtmlComponents.
                        </li>
                        <li>
                            The entire CshtmlComponent is passed as Model to the <code>.cshtml</code> file. This includes properties
                            inherited from TagHelper.
                        </li>
                    </ul>
                    <p></p>
                </section>
            </section>

            <section>
                <h2 class="scroll-anchor" id="change-log">
                    Changelog
                </h2>

                <section>
                    <h4>
                        V4.1.0
                    </h4>
                    <a href="/v4.1.0/">
                        V4.1.0 Documentation
                    </a>
                    <p>
                        Published: Dec 23, 2020
                    </p>
                    <p>
                        Exposed the <code>IHtmlHelper</code> that is dependency injected into each component
                        with the public property <code>HtmlHelper</code>.
                    </p>
                </section>

                <section>
                    <h4>
                        V4.0.0
                    </h4>
                    <a href="/v4.0.0/">
                        V4.0.0 Documentation
                    </a>
                    <p>
                        Published: Dec 20, 2020
                    </p>
                    <p>
                        Updated to .NET 5.0. Additionally, added the methods <code>Render</code>, <code>RenderAsync</code>, <code>RenderToString</code>
                        and <code>RenderToStringAsync</code> with which a component can manually be rendered. Manual rendering may be useful in, for
                        example, communicating with JavaScript.
                    </p>
                </section>

                <section>
                    <h4>
                        V3.1.0
                    </h4>
                    <a href="/v3.1.0/">
                        V3.1.0 Documentation
                    </a>
                    <p>
                        Published: Oct 30, 2020
                    </p>
                    <p>
                        Added constructors to <code>CshtmlComponentBase</code> and <code>CshtmlComponentReferenceableBase</code> to make development more convenient.
                        The main change was that from now on the path to the associated .cshtml file can be automatically generated by analyzing the namespace and
                        class name. This improves code maintainability and reduces unnecessary bugs. The path to the associated .csthml file can still be defined manually.
                    </p>
                </section>

                <section>
                    <h4>
                        V3.0.0
                    </h4>
                    <a href="/v3.0.0/">
                        V3.0.0 Documentation
                    </a>
                    <p>
                        Published: Oct 11, 2020
                    </p>
                    <p>
                        Breaking changes. Added support for head and body content injection with <code>CshtmlHead</code> and <code>CshtmlBody</code>.
                        Rewrote <code>CshtmlInitial</code> to no longer depend on the obsolete <code>Context</code> attribute. Upgrading from a
                        previous version should only minimally affect previous usage of <code>CshtmlInitial</code> (might even in most cases work
                        without any changes). Additionally, slight changes in dependency injection (Startup.cs).
                    </p>
                </section>

                <section>
                    <h4>
                        V2.2.0
                    </h4>
                    <a href="/v2.2.0/">
                        V2.2.0 Documentation
                    </a>
                    <p>
                        Published: Sep 26, 2020
                    </p>
                    <p>
                        Added support component reference capturing. This grants access to component properties outside
                        the components own context. See the Razor code in <a href="#example">Example</a> for an example
                        of how this is done. Note: This feature must be enabled at a component level.
                    </p>
                </section>

                <section>
                    <h4>
                        V2.1.0
                    </h4>
                    <a href="/v2.1.0/">
                        V2.1.0 Documentation
                    </a>
                    <p>
                        Published: Sep 20, 2020
                    </p>
                    <p>
                        Added support for <code>CshtmlInitial</code>, which allows component code be rendered once
                        per request, regardless of the number of instantiated components.
                    </p>
                </section>

                <section>
                    <h4>
                        V2.0.0
                    </h4>
                    <a href="/v2.0.0/">
                        V2.0.0 Documentation
                    </a>
                    <p>
                        Published: Sep 19, 2020
                    </p>
                    <p>
                        Breaking changes. Added support for named slots and added tag helper context and output as arguments
                        to <code>ProcessComponent</code>.
                    </p>
                </section>

                <section>
                    <h4>
                        V1.1.0
                    </h4>
                    <a href="/v1.1.0/">
                        V1.1.0 Documentation
                    </a>
                    <p>
                        Published: Sep 17, 2020
                    </p>
                    <p>
                        Added support for <code>TagMode</code>, which provides some extra customizability.
                    </p>
                </section>

                <section>
                    <h4>
                        V1.0.0
                    </h4>
                    <a href="/v1.0.0/">
                        V1.0.0 Documentation
                    </a>
                    <p>
                        Published: Sep 15, 2020
                    </p>
                    <p>
                        The initial release.
                    </p>
                </section>


            </section>

            <section>
                <h2 class="scroll-anchor" id="credits">
                    Credits
                </h2>

                <p>
                    CshtmlComponent was developed by <a href="https://acmion.com">Acmion</a> <a href="https://github.com/Acmion">(GitHub)</a>.
                </p>

                <p>
                    Contribute to CshtmlComponent in it's <a href="https://github.com/Acmion/CshtmlComponent">GitHub repository</a>.
                </p>

            </section>
        </main>

        <div style="height: 200px"></div>
        <div>
        </div>

    </body>

</html>